package com.gzhryc.shared_device.oem.h5.agent.mng.controllers.market;

import com.gzhryc.common.MatrixToImageWriter;
import com.gzhryc.common.NumberTools;
import com.gzhryc.common.StringTools;
import com.gzhryc.common.api.DefaultAPICodeConstants;
import com.gzhryc.common.api.DefaultAPIResponse;
import com.gzhryc.common.data.dto.AjaxResult;
import com.gzhryc.common.data.dto.ListResult;
import com.gzhryc.common.exceptions.LogicException;
import com.gzhryc.common.logging.Logger;
import com.gzhryc.net_marketing.api.protocol.account.*;
import com.gzhryc.net_marketing.core.enums.CloudPayAccountEnum;
import com.gzhryc.net_marketing.core.enums.GoodsOrderEnum;
import com.gzhryc.net_marketing.supplier.Supplier;
import com.gzhryc.net_marketing.supplier.SupplierManager;
import com.gzhryc.net_marketing.supplier.pay.dao.db.SupplierBusinessOrder;
import com.gzhryc.net_marketing.supplier.pay.services.SupplierBusinessOrderService;
import com.gzhryc.servlet.DtoConstants;
import com.gzhryc.servlet.WebUtils;
import com.gzhryc.servlet.annotation.Route;
import com.gzhryc.shared_device.base.enums.EPayType;
import com.gzhryc.shared_device.oem.h5.agent.mng.WebConstants;
import com.gzhryc.net_marketing.api.CloudPayAccountAPIService;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.*;

public class CloudPayAccountController {

    static Logger log = Logger.getLogger(CloudPayAccountController.class);

    @Route(value="/market/payAccount/index.html")
    public String list(HttpServletRequest request){
        //获取配置
        request.setAttribute("moneyStr","0");
        request.setAttribute("freezeMoneyStr", "0");
        request.setAttribute("updateMoneyDate", "---");
        request.setAttribute("updateFreezeMoneyDate", "---");

        Supplier supplier = SupplierManager.getSupplier();
        if(supplier != null && supplier.getAccountId() != null && StringTools.isNotBlank(supplier.getVisitToken())) {
            CloudPayAccountInfoResponse apiResp = CloudPayAccountAPIService.self().getAccountInfo(supplier.getAccountId(),supplier.getVisitToken());
            if(apiResp != null && DefaultAPICodeConstants.SUCCESS.equals(apiResp.getCode())){
                request.setAttribute("moneyStr", NumberTools.getMoneyStr(apiResp.getBody().getMoney()));
                request.setAttribute("freezeMoneyStr", NumberTools.getMoneyStr(apiResp.getBody().getFreezeMoney()));
                if(StringTools.isNotBlank(apiResp.getBody().getUpdateMoneyDate())) {
                    request.setAttribute("updateMoneyDate", apiResp.getBody().getUpdateMoneyDate());
                }
                if(StringTools.isNotBlank(apiResp.getBody().getUpdateFreezeMoneyDate())) {
                    request.setAttribute("updateFreezeMoneyDate", apiResp.getBody().getUpdateFreezeMoneyDate());
                }
            }
        }
        return "/market/account/index.html";
    }

    @Route(value="/market/payAccount/operate/list.data")
    public ListResult<CloudPayAccountOperateListResponse.OperateItem> listData(HttpServletRequest request){
        ListResult<CloudPayAccountOperateListResponse.OperateItem> result = new ListResult<>(DtoConstants.NULL_DATA, "暂无数据");
        Supplier supplier = SupplierManager.getSupplier();
        Integer pageNo = WebUtils.getInteger(request, "page", 1);
        Integer pageLimit = WebUtils.getInteger(request, "limit", WebConstants.PAGE_LIMIT);
        if(supplier != null && supplier.getAccountId() != null && StringTools.isNotBlank(supplier.getVisitToken())) {
            CloudPayAccountOperateListResponse apiResp = CloudPayAccountAPIService.self().findAccountOperateList(supplier.getAccountId()
                    ,supplier.getVisitToken(),pageNo,pageLimit);
            if(apiResp != null && DefaultAPICodeConstants.SUCCESS.equals(apiResp.getCode())){
                result.setCode(DtoConstants.SUCCESS, null);
                result.getBody().setTotal(apiResp.getBody().getTotal());
                result.getBody().setData(apiResp.getBody().getOperateItemList());
            }
        }
        return result;
    }

    @Route(value="/market/payAccount/deposit/order/list.data")
    public ListResult<CloudPayAccountDepositOrderListResponse.OrderItem> depositOrderListData(HttpServletRequest request){
        ListResult<CloudPayAccountDepositOrderListResponse.OrderItem> result = new ListResult<>(DtoConstants.NULL_DATA, "暂无数据");
        Integer pageNo = WebUtils.getInteger(request, "page", 1);
        Integer pageLimit = WebUtils.getInteger(request, "limit", WebConstants.PAGE_LIMIT);
        Supplier supplier = SupplierManager.getSupplier();
        if(supplier.getAccountId() != null && StringTools.isNotBlank(supplier.getVisitToken())) {
            CloudPayAccountDepositOrderListResponse apiResp = CloudPayAccountAPIService.self().findAccountDepositOrderList(supplier.getAccountId()
                    , supplier.getVisitToken(), pageNo, pageLimit);
            if (apiResp != null && DefaultAPICodeConstants.SUCCESS.equals(apiResp.getCode())) {
                result.setCode(DtoConstants.SUCCESS, null);
                result.getBody().setTotal(apiResp.getBody().getTotal());
                result.getBody().setData(apiResp.getBody().getOrderItemList());
            }
        }
        return result;
    }

    @Route(value="/market/payAccount/order/list.data")
    public ListResult<CloudPayAccountOrderListResponse.OrderItem> orderListData(HttpServletRequest request){
        ListResult<CloudPayAccountOrderListResponse.OrderItem> result = new ListResult<>(DtoConstants.NULL_DATA, "暂无数据");
        Supplier supplier = SupplierManager.getSupplier();
        Integer pageNo = WebUtils.getInteger(request, "page", 1);
        Integer pageLimit = WebUtils.getInteger(request, "limit", WebConstants.PAGE_LIMIT);
        Integer type = WebUtils.getInteger(request,"type");
        
        if(type != null && supplier != null && supplier.getAccountId() != null && StringTools.isNotBlank(supplier.getVisitToken())) {
            CloudPayAccountOrderListResponse apiResp = CloudPayAccountAPIService.self().findAccountOrderList(supplier.getAccountId()
                    , supplier.getVisitToken(), type, pageNo, pageLimit);
            if (apiResp != null && DefaultAPICodeConstants.SUCCESS.equals(apiResp.getCode())) {
                result.setCode(DtoConstants.SUCCESS, null);
                result.getBody().setTotal(apiResp.getBody().getTotal());
                result.getBody().setData(apiResp.getBody().getOrderItemList());
            }
        }
        return result;
    }

    @Route(value="/market/payAccount/withdraw/order/list.data")
    public ListResult<CloudPayAccountWithdrawOrderListResponse.OrderItem> withdrawOrderListData(HttpServletRequest request){
        ListResult<CloudPayAccountWithdrawOrderListResponse.OrderItem> result = new ListResult<>(DtoConstants.NULL_DATA, "暂无数据");
        Supplier supplier = SupplierManager.getSupplier();
        Integer pageNo = WebUtils.getInteger(request, "page", 1);
        Integer pageLimit = WebUtils.getInteger(request, "limit", WebConstants.PAGE_LIMIT);
        
        if(supplier != null && supplier.getAccountId() != null && StringTools.isNotBlank(supplier.getVisitToken())) {
            CloudPayAccountWithdrawOrderListResponse apiResp = CloudPayAccountAPIService.self().findAccountWithdrawOrderList(supplier.getAccountId()
                    , supplier.getVisitToken(), pageNo, pageLimit);
            if (apiResp != null && DefaultAPICodeConstants.SUCCESS.equals(apiResp.getCode())) {
                result.setCode(DtoConstants.SUCCESS, null);
                result.getBody().setTotal(apiResp.getBody().getTotal());
                result.getBody().setData(apiResp.getBody().getOrderItemList());
            }
        }
        return result;
    }

    @Route(value="/market/payAccount/recharge.html")
    public String recharge(HttpServletRequest request, HttpSession session){
    	Supplier supplier = SupplierManager.getSupplier();
        String tradeNo = WebUtils.getString(request,"tradeNo");
        if(StringTools.isNotBlank(tradeNo) && supplier != null){
            if(supplier.getAccountId() != null && StringTools.isNotBlank(supplier.getVisitToken())) {
                CloudPayAccountRechargeResponse apiResp = CloudPayAccountAPIService.self().recharge(supplier.getAccountId()
                        , supplier.getVisitToken(), null,null, tradeNo);
                if (apiResp != null) {
                    if (DefaultAPICodeConstants.SUCCESS.equals(apiResp.getCode())) {
                        request.setAttribute("payTypeName",EPayType.note(apiResp.getBody().getPayType()));
                        request.setAttribute("moneyStr",NumberTools.getMoneyStr(apiResp.getBody().getMoney()));
                    } else if (StringTools.isNotBlank(apiResp.getMsg())) {
                        request.setAttribute("errorMsg",apiResp.getMsg());
                    }
                }
            } else {
                request.setAttribute("errorMsg","未配置预存货款账号");
            }
        }
        List<EPayType> payTypeList = new ArrayList<>();
        payTypeList.add(EPayType.WXPay);
        payTypeList.add(EPayType.Alipay);
        request.setAttribute("payTypeList",payTypeList);
        return "/market/account/recharge.html";
    }

    @Route(value="/market/payAccount/recharge.do")
    public AjaxResult doRecharge(HttpServletRequest request, HttpSession session){
        AjaxResult result = new AjaxResult(DtoConstants.EXECUTE_ERROR,"充值失败，请稍后再试");
        Supplier supplier = SupplierManager.getSupplier();
        Double money = WebUtils.getDouble(request, "money");
        Integer payType = WebUtils.getInteger(request,"payType");
        if (money != null && money >= 1 && money <= 90000 && payType != null && supplier != null) {
            if(supplier.getAccountId() != null && StringTools.isNotBlank(supplier.getVisitToken())) {
                CloudPayAccountRechargeResponse apiResp = CloudPayAccountAPIService.self().recharge(supplier.getAccountId()
                        , supplier.getVisitToken(),payType,NumberTools.changeMoney(money), null);
                if (apiResp != null) {
                    if (DefaultAPICodeConstants.SUCCESS.equals(apiResp.getCode())) {
                        result.setCode(DtoConstants.SUCCESS, null);
                        Map<String,Object> data = new HashMap<>();
                        data.put("tradeNo",apiResp.getBody().getTradeNo());
                        data.put("payTypeName",EPayType.note(apiResp.getBody().getPayType()));
                        data.put("moneyStr",NumberTools.getMoneyStr(apiResp.getBody().getMoney()));
                        result.setBody(data);
                    } else if (StringTools.isNotBlank(apiResp.getMsg())) {
                        result.setMsg(apiResp.getMsg());
                    }
                }
            } else {
                result.setMsg("未配置预存货款账号");
            }
        } else {
            result.setMsg("请填写1-90000以内的充值金额");
        }
        return result;
    }

    @Route(value="/market/payAccount/recharge/cancel.do")
    public AjaxResult doCancelRecharge(HttpServletRequest request, HttpSession session){
        AjaxResult result = new AjaxResult(DtoConstants.EXECUTE_ERROR,"取消充值失败，请稍后再试");
        String tradeNo = WebUtils.getString(request, "tradeNo");
        if (StringTools.isNotBlank(tradeNo)) {
            Supplier supplier = SupplierManager.getSupplier();
            if(supplier.getAccountId() != null && StringTools.isNotBlank(supplier.getVisitToken())) {
                DefaultAPIResponse apiResp = CloudPayAccountAPIService.self().cancelRecharge(supplier.getAccountId()
                        , supplier.getVisitToken(),tradeNo);
                if (apiResp != null) {
                    if (DefaultAPICodeConstants.SUCCESS.equals(apiResp.getCode())) {
                        result.setCode(DtoConstants.SUCCESS, null);
                    } else if (StringTools.isNotBlank(apiResp.getMsg())) {
                        result.setMsg(apiResp.getMsg());
                    }
                }
            } else {
                result.setMsg("未配置预存货款账号");
            }
        } else {
            result.setMsg("参数错误");
        }
        return result;
    }

    @Route("/market/payAccount/recharge/qrcode.jpg")
    public void qrcodeImg(HttpServletRequest request, HttpServletResponse response, HttpSession session) {
        String tradeNo = WebUtils.getString(request, "tradeNo");
        if(StringTools.isNotBlank(tradeNo)){
            Supplier supplier = SupplierManager.getSupplier();
            if(supplier.getAccountId() != null && StringTools.isNotBlank(supplier.getVisitToken())) {
                CloudPayAccountRechargeResponse apiResp = CloudPayAccountAPIService.self().recharge(supplier.getAccountId()
                        ,supplier.getVisitToken(),null,null,tradeNo);
                if(apiResp != null) {
                    if (DefaultAPICodeConstants.SUCCESS.equals(apiResp.getCode())) {
                        try {
                            WebUtils.exportJPEG(response);
                            MatrixToImageWriter.writeToStream(apiResp.getBody().getQrcodeContent(), 250,
                                    250, "jpeg", response.getOutputStream());
                        } catch (IOException e) {
                            log.error(e.getMessage(), e);
                        }
                    }
                }
            }
        }
    }

    @Route(value="/market/payAccount/withdraw.html")
    public String withdraw(HttpServletRequest request, HttpSession session){
        return "/market/account/withdraw.html";
    }

    @Route(value="/market/payAccount/withdraw/payee/list.data")
    public ListResult<CloudPayAccountWithdrawPayeeListResponse.Payee> withdrawPayeeListData(HttpServletRequest request){
        ListResult<CloudPayAccountWithdrawPayeeListResponse.Payee> result = new ListResult<>(DtoConstants.NULL_DATA, "暂无数据");
        Supplier supplier = SupplierManager.getSupplier();
        if(supplier.getAccountId() != null && StringTools.isNotBlank(supplier.getVisitToken())) {
            CloudPayAccountWithdrawPayeeListResponse apiResp = CloudPayAccountAPIService.self().findAccountWithdrawPayeeList(supplier.getAccountId()
                    , supplier.getVisitToken(),null);
            if (apiResp != null && DefaultAPICodeConstants.SUCCESS.equals(apiResp.getCode())) {
                result.setCode(DtoConstants.SUCCESS, null);
                result.getBody().setData(apiResp.getBody().getPayeeList());
            }
        }
        return result;
    }

    @Route(value="/market/payAccount/withdraw.do")
    public AjaxResult doWithdraw(HttpServletRequest request, HttpSession session){
        AjaxResult result = new AjaxResult(DtoConstants.EXECUTE_ERROR,"取款失败，请稍后再试");
        Double money = WebUtils.getDouble(request, "money");
        Integer receivingType = WebUtils.getInteger(request,"receivingType");
        String receivingId = WebUtils.getString(request, "receivingId");
        String receivingName = WebUtils.getString(request, "receivingName");
        String receivingPhone = WebUtils.getString(request, "receivingPhone");
        if (money != null && receivingType != null && StringTools.isNotBlank(receivingId) && StringTools.isNotBlank(receivingName)
                && StringTools.isNotBlank(receivingPhone)) {
            if(money < 3 && money < 5000){
                result.setMsg("请填写3-5000以内的充值金额");
                return result;
            }
            Supplier supplier = SupplierManager.getSupplier();
            if(supplier.getAccountId() != null && StringTools.isNotBlank(supplier.getPayToken())) {
                CloudPayAccountWithdrawRequest apiReq = new CloudPayAccountWithdrawRequest();
                apiReq.getBody().setAccountId(supplier.getAccountId());
                apiReq.getBody().setAccountToken(supplier.getPayToken());
                apiReq.getBody().setReceivingId(receivingId);
                apiReq.getBody().setReceivingType(receivingType);
                apiReq.getBody().setReceivingName(receivingName);
                apiReq.getBody().setReceivingPhone(receivingPhone);
                apiReq.getBody().setMoney(NumberTools.changeMoney(money));
                CloudPayAccountWithdrawResponse apiResp = CloudPayAccountAPIService.self().withdraw(apiReq);
                if (apiResp != null) {
                    if (DefaultAPICodeConstants.SUCCESS.equals(apiResp.getCode())) {
                        result.setCode(DtoConstants.SUCCESS, null);
                    } else if (StringTools.isNotBlank(apiResp.getMsg())) {
                        result.setMsg(apiResp.getMsg());
                    }
                }
            } else {
                result.setMsg("未配置预存货款账号");
            }
        } else {
            result.setMsg("参数错误，请检查");
        }
        return result;
    }

    @Route(value="/market/payAccount/order/settlement.do")
    public AjaxResult doSettlement(HttpServletRequest request, HttpSession session){
        AjaxResult result = new AjaxResult(DtoConstants.EXECUTE_ERROR,"结算失败，请稍后再试");
        String businessTradeNo = WebUtils.getString(request,"businessTradeNo");

        try {
            SupplierBusinessOrder businessOrder = SupplierBusinessOrderService.self().getByTradeNo(businessTradeNo);
            if(businessOrder == null){
                throw new LogicException("未找到业务订单");
            }

            if(!GoodsOrderEnum.State.Finish.index().equals(businessOrder.getState())) {
                throw new LogicException("业务订单未完成");
            }
            Supplier supplier = SupplierManager.getSupplier();
            if (supplier.getAccountId() != null && StringTools.isNotBlank(supplier.getPayToken())) {
                //触发结算
                CloudPayAccountSettlementRequest apiReq = new CloudPayAccountSettlementRequest();
                apiReq.getBody().setAccountId(supplier.getAccountId());
                apiReq.getBody().setAccountToken(supplier.getPayToken());
                apiReq.getBody().setTradeNo(businessOrder.getPayTradeNo());
                apiReq.getBody().setBusinessTradeNo(businessOrder.getTradeNo());
                apiReq.getBody().setPayMoney(businessOrder.getPayMoney());
                apiReq.getBody().setSettlementType(CloudPayAccountEnum.SettlementType.PayeeRequest.index());
                apiReq.getBody().setNote("收款方请求" + businessOrder.getTradeNo() + "订单手动结算");

                CloudPayAccountSettlementResponse apiResp = CloudPayAccountAPIService.self().settlement(apiReq);
                if (apiResp != null) {
                    log.info("触发云账号结算响应：{{0:json}}", apiResp);
                    if (DefaultAPICodeConstants.SUCCESS.equals(apiResp.getCode())) {
                        result.setCode(DtoConstants.SUCCESS, null);
                    } else {
                        result.setMsg(apiResp.getMsg());
                    }
                } else {
                    log.error("触发云账号结算未响应");
                }
            }
        }catch (LogicException e){
            result.setMsg(e.getMessage());
        }
        return result;
    }

    @Route(value="/market/payAccount/withdraw/payee/add.html")
    public String addWithdrawPayee(HttpServletRequest request, HttpSession session){
        return "/market/account/withdrawPayee.html";
    }

    @Route("/market/payAccount/withdraw/payee/add/qrcode.jpg")
    public void addWithdrawPayeeQrcodeImg(HttpServletRequest request, HttpServletResponse response) {
        Supplier supplier = SupplierManager.getSupplier();
        if(supplier.getAccountId() != null && StringTools.isNotBlank(supplier.getPayToken())) {
            CloudPayAccountWithdrawPayeeAddResponse apiResp = CloudPayAccountAPIService.self().addWithdrawPayee(supplier.getAccountId()
                    ,supplier.getPayToken());
            if(apiResp != null && DefaultAPICodeConstants.SUCCESS.equals(apiResp.getCode())){
                try {
                    WebUtils.exportJPEG(response);
                    MatrixToImageWriter.writeToStream(apiResp.getBody().getQrcodeContent(), 250,
                            250, "jpeg", response.getOutputStream());
                } catch (IOException e) {
                    log.error(e.getMessage(), e);
                }
            }
        }
    }


}
